//
//  main.swift
//  turi
//
//  Created by 王渊鸥 on 2018/2/4.
//  Copyright © 2018年 王渊鸥. All rights reserved.
//

import Foundation
import CoreML
import AppKit



var swapFileUrl:URL?

func removeSwap() -> Bool {
    func parentPathOf(source:URL) -> URL {
        var comp = source.pathComponents
        comp.remove(at: 0)
        _ = comp.popLast()
        let upPath = "/" + comp.joined(separator: "/")
        return URL(fileURLWithPath: upPath)
    }
    
    guard let url = swapFileUrl else { return false}
    
    do {
        let parentPath = parentPathOf(source: url)
        let manager = FileManager.default
        try manager.removeItem(at: parentPath)
        return true
    } catch {
        return false
    }
}

// 清理工作
defer {
    _ = removeSwap()
}

enum CmdError : Error {
    case ParameterNumberError
    case JsonSyntaxError
    case JsonConvertError
    case FeatureNumberError
}

do {
    // 判断命令参数数量
    if CommandLine.argc < 3 {
        throw CmdError.ParameterNumberError
    }
    
    // 获取命令参数
    let jsonText = CommandLine.arguments[2]
    guard let jsonData = jsonText.data(using: String.Encoding.utf8) else {
        throw CmdError.JsonSyntaxError
    }
    
    // 命令参数中的JSON中转换成字典结构
    let dictOrigin = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String:Any]
    guard let dictSource = dictOrigin else {
        throw CmdError.JsonConvertError
    }
    var dict:[String:Double] = [:]
    for kv in dictSource {
        let key = kv.key
        let value = kv.value
        if let doubleValue = value as? Double {
            dict[key] = doubleValue
        }
    }
    
    // 获取模型文件
    let modelSource = CommandLine.arguments[1]
    let modelSourceUrl = URL(fileURLWithPath: modelSource)

    // 编译模型中间文件
    let modelDest = try MLModel.compileModel(at: modelSourceUrl)
    swapFileUrl = modelDest
    
    // 生成模型
    let model = try MLModel(contentsOf: modelDest)
    
    // 参数准备
    let provider = try MLDictionaryFeatureProvider(dictionary: dict)
    
    // 生成结果
    let result = try model.prediction(from: provider)
    if result.featureNames.count != 1 {
        throw CmdError.FeatureNumberError
    }
    
    // 输出结果
    let resultKey = result.featureNames.first!
    let resultValue = result.featureValue(for: resultKey)!.doubleValue
    print("{\"Code\":0, \"\(resultKey)\":\"\(resultValue)\"}")
} catch {
    _ = removeSwap()
    print("{\"Code\":-1, \"Error\":\"\(error.localizedDescription)\"}")
}
